/**
 * 
 */
package util;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

import java.util.AbstractMap;
import java.util.Iterator;
import java.util.Set;

/**
 * Trie Map where the internal list of children is stored in a HashMap.
 * null cannot be stored.
 * 
 * @author Joshua Lockerman
 * @param <V>
 *            the value-type stored in the Trie Map.
 * 
 */
public class TrieMap<V> extends AbstractMap<String, V> {
    
    private final TrieSet<V> entrySet;
    
    public TrieMap()
    {
        entrySet = new TrieSet<V>();
    }
    
    @Override
    public Set<java.util.Map.Entry<String, V>> entrySet()
    {
        return entrySet;
    }
    
    @Override
    public boolean containsKey(Object key)
    {
        if(key == null) {
            return false;
        }
        return get(key) != null;
    }
    
    public TrieSet<V>.TrieSearchResult findSuffixTree(String key)
    {
        return entrySet.findSuffixTree(key);
    }
    
    @Override
    public V get(Object key)
    {
        if( !(key instanceof String)) {
            return null;
        }
        String s = (String) key;
        return entrySet.getRoot().get(s);
    }
    
    @Override
    public V put(String key, V value)
    {
        checkNotNull(key);
        checkNotNull(value);
        checkArgument( !key.isEmpty());
        return entrySet.put(key, value);
    }
    
    @Override
    public V remove(Object key)
    {
        if( !(key instanceof String)) {
            return null;
        }
        String s = (String) key;
        return entrySet.removeEntry(s);
    }
    
    public Iterator<java.util.Map.Entry<String, V>> iterator() {
        return entrySet().iterator();
    }
    
}
